package io.demo.domain.dao.impl;

import cn.org.atool.fluent.mybatis.If;
import io.demo.domain.dao.base.StudentBaseDao;
import io.demo.domain.dao.intf.StudentDao;
import io.demo.domain.entity.StudentEntity;
import io.demo.domain.wrapper.StudentQuery;
import org.springframework.stereotype.Repository;

import java.util.Date;
import java.util.List;

import static cn.org.atool.fluent.mybatis.If.*;

/**
 * StudentDaoImpl: 数据操作接口实现
 *
 * 这只是一个减少手工创建的模板文件
 * 可以任意添加方法和实现, 更改作者和重定义类名
 * <p/>@author Powered By Fluent Mybatis
 */
@Repository
public class StudentDaoImpl extends StudentBaseDao implements StudentDao {

    @Override
    public List<StudentEntity> selectByNameOrGender(String name, Boolean isMale) {
        return super.defaultQuery()
                .where.userName().like(name, If::notBlank)
                .and.genderMan().eq(isMale, If::notNull).end()
                .of(mapper).listEntity();
        //.execute(super::listEntity);
    }

    @Override
    public int updateByPrimaryKeySelective(StudentEntity student) {
        return super.defaultUpdater()
                .set.userName().is(student.getUserName(), If::notBlank)
                .set.phone().is(student.getPhone(), If::notBlank)
                .set.genderMan().is(student.getGenderMan(), If::notNull).end()
                .where.id().eq(student.getId()).end()
                .of(mapper).updateBy();
        //.execute(super::updateBy);
    }

    @Override
    public StudentEntity selectByIdOrName(StudentEntity student) {
        return super.defaultQuery()
                .where.id().eq(student.getId(), If::notNull)
                .and.userName().eq(student.getUserName(), name -> isNull(student.getId()) && notBlank(name))
                .and.applyIf(items -> isNull(student.getId()) && isBlank(student.getUserName()), "1=2")
                .end()
                .of(mapper).findOne().orElse(null);
    }

    /**
     * 根据条件查询学生列表
     * 如果设置了积分, 加上积分条件
     * 如果设置了状态, 加上状态条件
     *
     * @return
     */
    @Override
    public List<StudentEntity> findByBirthdayAndBonusPoints(Date birthday, Long points, String status) {
        StudentQuery query = super.query()
                .where.birthday().eq(birthday)
                .and.bonusPoints().ge(points, If::notNull)
                .and.status().eq(status, If::notBlank).end();
        return mapper.listEntity(query);
    }

    public List<StudentEntity> findByBirthdayAndBonusPoints2(Date birthday, Long points, String status) {
        StudentQuery query = super.query();
        query.where.birthday().eq(birthday);
        if (points != null) {
            query.where.bonusPoints().ge(points);
        }
        if (status != null && !status.trim().isEmpty()) {
            query.where.status().eq(status).end();
        }
        return mapper.listEntity(query);
    }

    /**
     * 查询积分点数大于等于指定值，并且未逻辑删除的所有学生
     *
     * @param minBonusPoints 最少积分
     * @return 符合条件的学生列表
     */
    public List<StudentEntity> selectStudents(int minBonusPoints) {
        return super.query()
                .where.bonusPoints().ge(minBonusPoints)
                .and.isDeleted().eq(false).end()
                .of(mapper).listEntity();
    }

    /**
     * 只查询id, user_name字段，使用生成的辅助类*Mapping显式指定字段名称
     *
     * @param minBonusPoints
     * @return
     */
    public List<StudentEntity> selectUserNames(int minBonusPoints) {
        return super.query()
                //.select.apply(id, userName).end()
                .select.id().userName().end()
                .where.bonusPoints().ge(minBonusPoints)
                .and.isDeleted().eq(false).end()
                .of(mapper).listEntity();
    }

    /**
     * 查询 主键id, 以及gmt开头的时间字段
     **/
    public List<StudentEntity> selectPredicateStudent(int minBonusPoints) {
        StudentQuery query = super.query()
                .selectId()
                .select.apply(f -> f.getColumn().startsWith("gmt")).end()
                .where.bonusPoints().ge(minBonusPoints)
                .and.isDeleted().eq(false).end();
        return super.mapper.listEntity(query);
    }
}
